﻿using CommunicationLib;
using CommunicationLib.Model;
using PlcLib.Enums;
using PlcLib.Interface;
using PlcLib.Model;
using PlcLib.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PlcLib.Base
{
    public abstract class PlcBase : ObservableObject, IPlc
    {

        //事件
        public abstract event Action<object, PlcEventArgs> OnMessage;
        public abstract event Action<object, PlcEventArgs> OnError;
        public abstract event Action<object, DataPackage> OnSend;
        public abstract event Action<object, DataPackage> OnReceived;

        protected Communication communication = new Communication();//与下位机的通讯类
        protected AutoResetEvent sendWaiter = new AutoResetEvent(false);//发送线程的同步器
        protected Queue<DataPackage> sendPackages = new Queue<DataPackage>();//下发指令队列
        protected readonly object sendLocker = new object();//下发指令队列锁
        protected List<DataPackage> receivePackages = new List<DataPackage>();//接收指令集合
        protected readonly object receiveLocker = new object(); //接收指令集合锁
        protected CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();//线程取消
        protected long CommandNumber = 1;

        public abstract void Initialize(Net net);
        public abstract void Initialize(Port port);
        public abstract IPlcResult Read(Command command);
        public abstract Task<IPlcResult> ReadAsync(Command command);
        public abstract IPlcResult Send(byte[] array);
        public abstract Task<IPlcResult> SendAsync(byte[] array);
        public abstract IPlcResult Start(Action action);
        public abstract IPlcResult Write(Command command, int data);
        public abstract Task<IPlcResult> WriteAsync(Command command, int data);
        public abstract IPlcResult Write(Command command, List<int> data);
        public abstract Task<IPlcResult> WriteAsync(Command command, List<int> data);
        public abstract IPlcResult<T> Read<T>(Command command);
        public abstract IPlcResult<T> Write<T>(Command command, T data);
        public abstract Task<IPlcResult<T>> ReadAsync<T>(Command command);
        public abstract Task<IPlcResult<T>> WriteAsync<T>(Command command, T data);

        public virtual void Stop()
        {
            communication.Stop();
            cancellationTokenSource.Cancel();
        }


        protected long GetCommandNumber()
        {
            return CommandNumber++;
        }

        //一些属性成员


        private ConnectedState connectedState;
        /// <summary>
        /// 通讯状态
        /// </summary>
        public ConnectedState ConnectedState
        {
            get { return connectedState; }
            set { connectedState = value; RaisePropertyChanged(); }
        }


    }
}
